struct varlist;
struct jitngin;
struct varh;
struct transblock;

// typedef int(*rtexecfn)(int64*,struct ins *);

#define F_VAR_VALID 1
#define F_VAR_STACK 2
#define F_VAR_HEAP 4

struct var { // var
    int flg; // 1: 有效 2:局部变量,栈区sz 4:全局变量,堆区; 
    enum var_type type;
    uint sz;
    /* for heap */
    void * heapaddr;
    /* for stack */
    uint stackoff; // 8字节对齐 , 可通过fp生成地址
};

// !!! 栈向上生长

#define F_INS_VALID 1
#define F_INS_TB 2
#define F_INS_FUNC 4
#define F_INS_LBL 8
#define F_INS_RTC 16

/* str和space在栈中是指针类型,栈中所有数据都是i64 */
/* 如检测到ret,则释放所有局部变量,控制栈帧 */
/* 栈控制指令只有call和ret */
/* call指令: fp-=ins.varspace fp-=sizeof gregs [fp]<-gregs ra<-pc+1 pc<-func 局部变量=fp-var.stackoff */
/* ret指令: gregs<-[fp] fp+=ins.varspace pc<-ra */
struct ins {
    int flg; // flg&1:有效 flg&2:tb已生成 flg&4:函数标签 flg&8:局部标签 flg&16:运行时控制
    enum ins_type type;
    enum reg_nm r0, r1, r2; // 统一使用64位处理 NOTE:r1是STI,LDI的idx
    int64 imm;
    enum var_type addrmode; // 寻址方式,按照哪种类型寻址? NOTE:str和space按ptr处理
    enum var_type casttype; // 类型转换
    enum rtc_type rtc;
    char * func; // 函数名
    char * lbl; // 局部标签
    uint varspace; // 整个函数局部变量所占空间, 8字节对齐, call和ret指令调整栈帧时使用, FP+varspace为栈顶
    struct var * v;
    // void * stack; // 默认栈底
    struct transblock * tb; 
    enum iadr_type iadr; // 间址类型
    struct {
        enum var_type type;
        char * str;
        uint space;
        int64 imm;
    } asgn;
    uint execnt; // 使用解释器执行次数 
    uint j; // 跳转地址
};

// #define MAX_NRVAR 128
// struct varlist {
//     uint64 sz;
//     struct var hashmap[MAX_NRVAR];
// };

struct dataseg {
#define MAX_DSMEMSZ 0x2000000U // 32M
#define DS_STACKSZ 0x200000U // 2M
#define DS_HEAPSZ (MAX_DSMEMSZ-DS_STACKSZ)
    void * heap;
    void * stack;
    uint sz;
    char mem[MAX_DSMEMSZ];
};
#define MAX_NRTEXTINS 10240//代码段最多多少条指令
struct textseg {
    uint sz;
    uint end;
    struct ins insls[MAX_NRTEXTINS];
};

/* note:运行时需要 */

struct runtime {
    struct varh * varheap;
    struct dataseg * data;
    struct textseg * text;
    struct jitngin * jit;
    uint64 * regs;
    enum {
        RUNTIME_DEFAULT = 0,
        RUNTIME_RT,
        RUNTIME_JIT
    } mode;
    struct {
        #define MAX_NRSTKVAR 128 // 最多每个栈中有128个变量
        struct var *v[MAX_NRSTKVAR];
        uint len;
    } stkvar; // 栈中引用变量, ret指令释放变量时用, 包括所有变量
};